// 
// impressionistDoc.h
//
// header file for Doc 
//

#ifndef ImpressionistDoc_h
#define ImpressionistDoc_h

#include <list>

#include "impressionist.h"
#include "bitmap.h"
#include "PixelNode.h"

using namespace std;

typedef enum {kPaintOriginal, kPaintPixelGraph, kPaintCostLinkGraph,kPaintCostTree, kPaintMinPath} PaintState_t;

class ImpressionistUI;

class ImpressionistDoc 
{
public:
	ImpressionistDoc();

	void	setUI(ImpressionistUI* ui);		// Assign the UI to use

	int		loadImage(char *iname);			// called by the UI to load image
	int		saveImage(char *iname);			// called by the UI to save image
	int		savePixelGraph(char *iname);	// called by the UI to save DEBUG pixel graph
	int		saveCostLinkGraph(char *iname);	// called by the UI to save DEBUG cost link graph
	int		saveContour(char *iname);		// called by the UI to save image with contour
	int		generateMask();
	int		saveMask(char *iname);			// called by the UI to save mask

	int     clearCanvas();                  // called by the UI to clear the drawing canvas
	//void	setBrushType(int type);			// called by the UI to set the brushType
	//int		getSize();						// get the UI size
	//void	setSize(int size);				// set the UI size
	char*	getImageName();					// get the current image name
	void	refresh();
	

// Attributes
public:
	// Dimensions of original window.
	int				m_nWidth, 
					m_nHeight;
	// Scale
	double			m_scale;
	// Dimensions of the paint window.
	int				m_nPaintWidth, 
					m_nPaintHeight;	
	// Maximum depth of minimal path tree
	int				maxCounter;
	// Number of expanded nodes, set by UI
	int				numExpandedNodes;
	// Bitmaps for original image and painting.
	unsigned char*	m_ucBitmap;
	unsigned char*	m_ucPainting;

	// Cost graph for the image.
	PixelNode*		cost_graph;
	// DEBUG Pixel Node and Cost link array.
	unsigned char*	m_debugPixelNode;
	unsigned char*	m_debugCostLink;
	// Image with contour	
	list<Point>    closedContour;
	unsigned char*  m_imageWithContour;
	// Mask matrix and scissored fragment
	bool*			m_mask;
	unsigned char*	m_fragment;

	// All seedpts
	list<Point>		m_seedPoints;
	// min paths
	list< list<Point> > m_minPaths;
	// traverse order
	list<Point>		m_traverseList;

	// Paint mode: decide which picture to draw in the window
	PaintState_t	m_currentPaintMode;

	// The current active brush.
	//ImpBrush*			m_pCurrentBrush;	
	// Size of the brush.
	//int m_nSize;							

	ImpressionistUI*	m_pUI;

// Operations
public:
	// Get the color of the original picture at the specified coord
	GLubyte* GetOriginalPixel( int x, int y );   
	// Get the color of the original picture at the specified point	
	GLubyte* GetOriginalPixel( const Point p ); 
	// Check whether a point is in valid range
	bool in_valid_range(int y, int x);
// Added operations
public:
	// Calculate the cost graph and pixels for other display mode
	void cal_cost_graph();
	void cal_debug_pixel_node();
	void cal_debug_cost_link();
	// Operations about the seed points	
	bool empty_seedPoint();
	void add_seedPoint(Point pt);
	void remove_seedPoint();
	void clear_seedPoint();
	// Calculate path tree and min path
	void cal_path_tree(Point seed);
	list<Point> cal_min_path(Point end);

private:
	char			m_imageName[256];

// Added functions
private:
	
	double get_horizontal_link_cost(int x1,int y1, int x2, int y2);
	double get_vertical_link_cost(int x1, int y1, int x2, int y2);
	double get_diagonal_link_cost(int x1, int y1, int x2, int y2);
	Point pick_point_outside_contour();
};

extern void MessageBox(char *message);

#endif
